import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';

import Calendar from 'rc-calendar';
import zhCN from 'rc-calendar/lib/locale/zh_CN';
import RcDatePicker from 'rc-calendar/lib/Picker';
import TimePickerPanel from 'rc-time-picker/lib/Panel';

import { Moment } from 'moment';
import 'moment/locale/zh-cn';

import { Icon } from '../icon';

export interface IDatePickerInputProps {
  placeholder?: string;
  disabled?: boolean;
  xSmall?: boolean;
  small?: boolean;
  large?: boolean;
  xLarge?: boolean;
}

export interface IDatePickerProps extends IDatePickerInputProps {
  // calendar?: React.ReactNode;
  // align?: object;
  // animation?: string;
  // transitionName?: string;
  // defaultValue?: Moment;
  // onOpenChange?: (open: boolean) => void;
  onChange?: (value: Moment) => void;
  getCalendarContainer?: () => HTMLElement;
  disabledDate?: (current: Moment) => boolean;
  className?: string;
  value?: Moment | null;
  open?: boolean;
  // Calendar props
  showTime?: boolean;
  showSecond?: boolean;
  minuteStep?: number;
  disabledHours?: () => number[];
  disabledMinutes?: (hour?: number) => number[];
  disabledSeconds?: (hour?: number, minute?: number) => number[];
}

export interface IDatePickerState {
  open?: boolean;
  initialOpen?: boolean;
}

export class DatePicker extends React.Component<IDatePickerProps, IDatePickerState> {
  public static propTypes = {
    value: PropTypes.any,
  };

  public static defaultProps = {
    showTime: false,
    showSecond: true,
    // minuteStep: false,
  };

  public static getDerivedStateFromProps(nextProps: IDatePickerProps, prevState: IDatePickerState) {
    if (nextProps.open !== prevState.initialOpen) {
      return {
        open: nextProps.open,
        initialOpen: nextProps.open,
      };
    }
    return null;
  }

  constructor(props: IDatePickerProps) {
    super(props);

    this.state = {
      open: props.open || false,
      initialOpen: props.open,
    };

    this.onOpenChange = this.onOpenChange.bind(this);
  }

  public onOpenChange(open: boolean) {
    this.setState({ open });
  }

  public render() {
    const {
      placeholder,
      disabled,
      onChange,
      disabledDate,
      getCalendarContainer,
      className,
      xLarge,
      large,
      small,
      xSmall,
      showTime,
      showSecond,
      minuteStep,
      disabledHours,
      disabledMinutes,
      disabledSeconds,
    } = this.props;

    const timePicker = <TimePickerPanel
      showSecond={showSecond}
      minuteStep={minuteStep}
      disabledHours={disabledHours}
      disabledMinutes={disabledMinutes}
      disabledSeconds={disabledSeconds} />;

    const calendar = (<Calendar
      locale={zhCN}
      timePicker={showTime ? timePicker : null}
      disabledDate={disabledDate}
    />);

    const classes = {
      'date-picker-xl': xLarge,
      'date-picker-lg': large,
      'date-picker-sm': small,
      'date-picker-xs': xSmall,
    };

    return (
      <div
        className={classNames('date-picker', className, classes)}
        style={{ position: 'relative' }}
      >
        <RcDatePicker
          calendar={calendar}
          animation="slide-up"
          disabled={disabled}
          value={this.props.value}
          open={this.state.open}
          onOpenChange={this.onOpenChange}
          getCalendarContainer={getCalendarContainer}
          onChange={onChange}
        >
          {
            ({ value }: { value: Moment }) => {
              return (
                <div className="date-picker-controller">
                  <input
                    placeholder={placeholder}
                    readOnly
                    tabIndex={-1}
                    value={value && value.format(showTime ?
                      (showSecond ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD HH:mm') : 'YYYY-MM-DD')
                      || ''}
                  />
                  <Icon type="date" />
                </div>
              );
            }
          }
        </RcDatePicker>
      </div>
    );
  }
}
